package com.auxgroup.hr.front.commons.utils;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import javax.net.ssl.SSLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSONObject;
 
public class HttpClientUtil {
    private static final Log logger = LogFactory.getLog(HttpClientUtil.class);
    private static final String ENCODING = "UTF-8";
    private static final String CONTENT_TYPE = "application/json";
    private static CloseableHttpClient httpClient;
    
    static {
        RequestConfig requestConfig = RequestConfig.custom() 
                .setSocketTimeout(5000)  
                .setConnectTimeout(5000)  
                .setConnectionRequestTimeout(5000)
                .build(); 
        
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(400);
        cm.setDefaultMaxPerRoute(200);
        
        HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                if (executionCount >= 2) {
                    // Do not retry if over max retry count
                    return false;
                }
                if (exception instanceof UnknownHostException) {
                    // Unknown host  修改代码让不识别主机时重试，实际业务当不识别的时候不应该重试，再次为了演示重试过程，执行会显示5次下面的输出
                    //System.out.println("不识别主机重试");  
                    return true;
                }
                if (exception instanceof ConnectTimeoutException) {
                    //request connection time out
                    //System.out.println("===ConnectTimeoutException==="); 
                    return false;
                }
                if (exception instanceof SocketTimeoutException) {
                    // response time out
                    System.out.println("===SocketTimeoutException==="); 
                    return false;
                }
                if (exception instanceof InterruptedIOException) {
                    //Timeout
                    return false;
                }
                if (exception instanceof SSLException) {
                    // SSL handshake exception
                    return false;
                }
                HttpClientContext clientContext = HttpClientContext.adapt(context);
                HttpRequest request = clientContext.getRequest();
                boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
                if (idempotent) {
                    // Retry if the request is considered idempotent
                    return true;
                }
                return false;
            }
        };
        
        httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig)
            .setConnectionManager(cm).setRetryHandler(httpRequestRetryHandler).build();
        
    }
    
    /**
     * POST请求
     * @param URL
     * @param json
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static JSONObject doPost(final String URL,JSONObject json) throws ClientProtocolException, IOException{
        HttpPost post = new HttpPost(URL);
        JSONObject response = null;
        CloseableHttpResponse res = null;
        int statusCode = 0;
        try {
            if(json != null){
                StringEntity entity  = new StringEntity(json.toString(),ENCODING);
                entity .setContentEncoding(ENCODING);
                entity .setContentType(CONTENT_TYPE);
                post.setEntity(entity);
            }
            logger.info("请求参数：url={"+URL+"},josn={"+json.toString()+"}");
            res = httpClient.execute(post);
            statusCode = res.getStatusLine().getStatusCode();
            if(statusCode != HttpStatus.SC_OK){
                return null;
            }
            HttpEntity entity = res.getEntity();
            if(entity != null){
                String result = EntityUtils.toString(entity);
                response = JSONObject.parseObject(result);
                logger.info("返回数据："+result);
            }
        } /*catch (ClientProtocolException e) {
            logger.error(e.getMessage());
            e.printStackTrace();  
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage());
            e.printStackTrace();  
        } catch (IOException e) { 
            logger.error(e.getMessage());
            e.printStackTrace();  
        }*/ finally {  
            try {
                if(res != null)
                    res.close();
            } catch (IOException e) {  
                logger.error(e.getMessage() ,e);
                e.printStackTrace();  
            }
        }
        return response;
    }
    
    
    /**
     * GET请求
     * @param URL
     * @return
     */
    public static String doGet1(final String URL){
        CloseableHttpClient client = HttpClients.createDefault();
        HttpGet get = new HttpGet(URL);
        String result = null;
        int statusCode = 0;
        try {
            CloseableHttpResponse res = client.execute(get);
            statusCode = res.getStatusLine().getStatusCode();
            if(statusCode == HttpStatus.SC_OK){
                HttpEntity entity = res.getEntity();
                if(entity !=null){
                    result = EntityUtils.toString(entity);
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();  
        } catch (UnsupportedEncodingException e1) {  
            e1.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            // 关闭连接,释放资源    
            try { 
                if(client != null){
                    client.close();  
                }
            } catch (IOException e) {  
                logger.error(e.getMessage() ,e);
                e.printStackTrace();  
            }
        }
        return result;
    }
    
    
    /**
     * GET请求
     * @param URL
     * @return
     */
    public static JSONObject doGet(final String URL){
        CloseableHttpClient client = HttpClients.createDefault();
        HttpGet get = new HttpGet(URL);
        JSONObject response = null;
        int statusCode = 0;
        try {
            CloseableHttpResponse res = client.execute(get);
            statusCode = res.getStatusLine().getStatusCode();
            if(statusCode == HttpStatus.SC_OK){
                HttpEntity entity = res.getEntity();
                if(entity !=null){
                    String result = EntityUtils.toString(entity);
                    response = JSONObject.parseObject(result);
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();  
        } catch (UnsupportedEncodingException e1) {  
            e1.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            // 关闭连接,释放资源    
            try { 
                if(client != null){
                    client.close();  
                }
            } catch (IOException e) {  
                logger.error(e.getMessage() ,e);
                e.printStackTrace();  
            }
        }
        return response;
    }
}
